home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / drivers / scsi / st.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  37.7 KB  |  1,338 lines

  1. /*
  2.   SCSI Tape Driver for Linux
  3.  
  4.   Version 0.02 for Linux 0.98.4 and Eric Youngdale's new scsi driver
  5.  
  6.   History:
  7.   Rewritten from Dwayne Forsyth's SCSI tape driver by Kai Makisara.
  8.  
  9.   Features:
  10.   - support for different block sizes and internal buffering
  11.   - support for fixed and variable block size (within buffer limit;
  12.     blocksize set to zero)
  13.   - *nix-style ioctl with codes from mtio.h from the QIC-02 driver by
  14.     Hennus Bergman (command MTSETBLK added)
  15.   - character device
  16.   - rewind and non-rewind devices
  17.   - capability to handle several tape drives simultaneously
  18.   - one buffer if one drive, two buffers if more than one drive (limits the
  19.     number of simultaneously open drives to two)
  20.   - write behind
  21.   - seek and tell (Tandberg compatible and SCSI-2)
  22.  
  23.   Devices:
  24.   Autorewind devices have minor numbers equal to the tape numbers (0 > ).
  25.   Nonrewind device has the minor number equal to tape number + 128.
  26.  
  27.   Problems:
  28.   The end of media detection may not work correctly because of the buffering.
  29.   If you want to do multiple tape backups relying on end of tape detection,
  30.   you should disable write behind and in addition to that check that the
  31.   tapes are readable.
  32.  
  33.   Copyright 1992, 1993 Kai Makisara
  34.          email makisara@vtinsx.ins.vtt.fi or Kai.Makisara@vtt.fi
  35.  
  36.   Last modified: Sat Jul 10 17:40:05 1993 by root
  37. */
  38.  
  39. #include <linux/fs.h>
  40. #include <linux/kernel.h>
  41. #include <linux/sched.h>
  42. #include <linux/string.h>
  43. #include <linux/errno.h>
  44. #include <linux/mtio.h>
  45. #include <linux/ioctl.h>
  46. #include <linux/fcntl.h>
  47. #include <asm/segment.h>
  48. #include <asm/system.h>
  49.  
  50. #define MAJOR_NR SCSI_TAPE_MAJOR
  51. #include "../block/blk.h"
  52. #include "scsi.h"
  53. #include "scsi_ioctl.h"
  54. #include "st.h"
  55.  
  56. #define MAX_RETRIES 0
  57. #define MAX_READY_RETRIES 5
  58. #define NO_TAPE  NOT_READY
  59.  
  60. /* Uncomment the following if you want the rewind, etc. commands return
  61.    before command completion. */
  62. /* #define ST_NOWAIT */
  63.  
  64. /* Uncomment the following if you want the tape to be positioned correctly
  65.    within file after close (the tape is positioned correctly with respect
  66.    to the filemarks even wihout ST_IN_FILE_POS defined */
  67. /* #define ST_IN_FILE_POS */
  68.  
  69. /* #define DEBUG */
  70.  
  71. #define ST_TIMEOUT 9000
  72. #define ST_LONG_TIMEOUT 200000
  73.  
  74. /* Number of ST_BLOCK_SIZE blocks in the buffers */
  75. #define ST_BUFFER_BLOCKS 64
  76. /* Write-behind can be disabled by setting ST_WRITE_THRESHOLD_BLOCKS equal to or
  77.    larger than ST_BUFFER_BLOCKS */
  78. #define ST_WRITE_THRESHOLD_BLOCKS 60
  79. #define ST_BLOCK_SIZE 512
  80. #define ST_BUFFER_SIZE (ST_BUFFER_BLOCKS * ST_BLOCK_SIZE)
  81. #define ST_WRITE_THRESHOLD (ST_WRITE_THRESHOLD_BLOCKS * ST_BLOCK_SIZE)
  82.  
  83. /* The buffer size should fit into the 24 bits reserved for length in the
  84.    6-byte SCSI read and write commands. */
  85. #if ST_BUFFER_SIZE >= (2 << 24 - 1)
  86. #error "Buffer size should not exceed (2 << 24 - 1) bytes!"
  87. #endif
  88.  
  89. static int st_nbr_buffers;
  90. static ST_buffer *st_buffers[2];
  91.  
  92. static Scsi_Tape * scsi_tapes;
  93. int NR_ST=0;
  94. int MAX_ST=0;
  95.  
  96. static int st_int_ioctl(struct inode * inode,struct file * file,
  97.          unsigned int cmd_in, unsigned long arg);
  98.  
  99.  
  100.  
  101.  
  102. /* Wakeup from interrupt */
  103. static void st_sleep_done (Scsi_Cmnd * SCpnt)
  104. {
  105.   int st_nbr;
  106.  
  107.   if ((st_nbr = SCpnt->request.dev) < NR_ST && st_nbr >= 0) {
  108.     if (scsi_tapes[st_nbr].buffer->writing &&
  109.     (SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
  110.     (SCpnt->sense_buffer[2] & 0x40))
  111.       scsi_tapes[st_nbr].buffer->last_result = INT_MAX;
  112.     else
  113.       scsi_tapes[st_nbr].buffer->last_result = SCpnt->result;
  114.     if (scsi_tapes[st_nbr].buffer->writing)
  115.       SCpnt->request.dev = -1;
  116.     else
  117.       SCpnt->request.dev = 0xffff;
  118.     if (scsi_tapes[st_nbr].buffer->writing <= 0)
  119.       wake_up( &scsi_tapes[st_nbr].waiting );
  120.   }
  121. #ifdef DEBUG
  122.   else
  123.     printk("st?: Illegal interrupt device %x\n", st_nbr);
  124. #endif
  125. }
  126.  
  127. /* Convert the result to success code */
  128. static int st_chk_result(Scsi_Cmnd * SCpnt)
  129. {
  130. #ifdef DEBUG
  131.   int dev = SCpnt->request.dev;
  132. #endif
  133.   int result = SCpnt->result;
  134.   unsigned char * sense = SCpnt->sense_buffer;
  135.  
  136.   if (!result)
  137.     return 0;
  138. #ifdef DEBUG
  139.   printk("st%d: Error: %x\n", dev, result);
  140.   print_sense("st", SCpnt);
  141. #endif
  142.   if ((sense[0] & 0x70) == 0x70 &&
  143.        ((sense[2] & 0x80) /* || ((sense[2] & 0x0f) == 8) */ ))
  144.     return 0;
  145.   return (-EIO);
  146. }
  147.  
  148.  
  149. #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
  150. /* Handle the write-behind checking */
  151. static void write_behind_check(int dev)
  152. {
  153.   cli();
  154.   if (scsi_tapes[dev].buffer->last_result < 0) {
  155.     scsi_tapes[dev].buffer->writing = (- scsi_tapes[dev].buffer->writing);
  156.     sleep_on( &scsi_tapes[dev].waiting );
  157.     scsi_tapes[dev].buffer->writing = (- scsi_tapes[dev].buffer->writing);
  158.   }
  159.   sti();
  160.  
  161.   if (scsi_tapes[dev].buffer->writing < scsi_tapes[dev].buffer->buffer_bytes)
  162.     memcpy(scsi_tapes[dev].buffer->b_data,
  163.        scsi_tapes[dev].buffer->b_data + scsi_tapes[dev].buffer->writing,
  164.        scsi_tapes[dev].buffer->buffer_bytes -
  165.        scsi_tapes[dev].buffer->writing);
  166.   scsi_tapes[dev].buffer->buffer_bytes -= scsi_tapes[dev].buffer->writing;
  167.   scsi_tapes[dev].buffer->writing = 0;
  168.  
  169.   return;
  170. }
  171. #endif
  172.  
  173.  
  174. /* Flush the write buffer (never need to write if variable blocksize). */
  175. static int flush_write_buffer(int dev)
  176. {
  177.   int offset, transfer, blks;
  178.   int result;
  179.   unsigned char cmd[10];
  180.   Scsi_Cmnd *SCpnt;
  181.  
  182. #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
  183.   if (scsi_tapes[dev].buffer->writing) {
  184.     write_behind_check(dev);
  185.     if (scsi_tapes[dev].buffer->last_result) {
  186. #ifdef DEBUG
  187.       printk("st%d: Async write error %x.\n", dev,
  188.          scsi_tapes[dev].buffer->last_result);
  189. #endif
  190.       return (-EIO);
  191.     }
  192.   }
  193. #endif
  194.  
  195.   result = 0;
  196.   if (scsi_tapes[dev].dirty==1) {
  197.     SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
  198.  
  199.     offset = scsi_tapes[dev].buffer->buffer_bytes;
  200.     transfer = ((offset + scsi_tapes[dev].block_size - 1) /
  201.         scsi_tapes[dev].block_size) * scsi_tapes[dev].block_size;
  202. #ifdef DEBUG
  203.     printk("st%d: Flushing %d bytes.\n", dev, transfer);
  204. #endif
  205.     memset(scsi_tapes[dev].buffer->b_data + offset, 0, transfer - offset);
  206.  
  207.     SCpnt->sense_buffer[0] = 0;
  208.     memset(cmd, 0, 10);
  209.     cmd[0] = WRITE_6;
  210.     cmd[1] = 1;
  211.     blks = transfer / scsi_tapes[dev].block_size;
  212.     cmd[2] = blks >> 16;
  213.     cmd[3] = blks >> 8;
  214.     cmd[4] = blks;
  215.     SCpnt->request.dev = dev;
  216.     scsi_do_cmd (SCpnt,
  217.          (void *) cmd, scsi_tapes[dev].buffer->b_data, transfer,
  218.          st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
  219.  
  220.     if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  221.  
  222.     if (SCpnt->result != 0) {
  223.       printk("st%d: Error on flush:\n", dev);
  224. #ifdef DEBUG
  225.       st_chk_result(SCpnt);
  226. #endif
  227.       result = (-EIO);
  228.     }
  229.     else {
  230.       scsi_tapes[dev].dirty = 0;
  231.       scsi_tapes[dev].buffer->buffer_bytes = 0;
  232.     }
  233.     SCpnt->request.dev = -1;  /* Mark as not busy */
  234.   }
  235.   return result;
  236. }
  237.  
  238.  
  239. /* Flush the tape buffer. The tape will be positioned correctly unless
  240.    seek_next is true. */
  241. static int flush_buffer(struct inode * inode, struct file * filp,
  242.             int seek_next)
  243. {
  244.   int dev;
  245.   int backspace, result;
  246.  
  247.   dev = MINOR(inode->i_rdev) & 127;
  248.  
  249.   if (scsi_tapes[dev].rw == 2)  /* Writing */
  250.     return flush_write_buffer(dev);
  251.  
  252.   if (scsi_tapes[dev].block_size == 0)
  253.     return 0;
  254.  
  255.   backspace = (scsi_tapes[dev].buffer->buffer_bytes +
  256.     scsi_tapes[dev].buffer->read_pointer) / scsi_tapes[dev].block_size -
  257.       (scsi_tapes[dev].buffer->read_pointer + scsi_tapes[dev].block_size - 1) /
  258.     scsi_tapes[dev].block_size;
  259.   scsi_tapes[dev].buffer->buffer_bytes = 0;
  260.   scsi_tapes[dev].buffer->read_pointer = 0;
  261.   result = 0;
  262.   if (!seek_next && backspace > 0) {
  263.     result = st_int_ioctl(inode, filp, MTBSR, backspace);
  264.     if (!result) {
  265.       scsi_tapes[dev].eof = 0;
  266.       scsi_tapes[dev].eof_hit = 0;
  267.     }
  268.   }
  269.   return result;
  270.  
  271. }
  272.  
  273.  
  274. /* Open the device */
  275. static int scsi_tape_open(struct inode * inode, struct file * filp)
  276. {
  277.     int dev;
  278.     unsigned short flags;
  279.     int i;
  280.     unsigned char cmd[10];
  281.     Scsi_Cmnd * SCpnt;
  282.  
  283.     dev = MINOR(inode->i_rdev) & 127;
  284.     if (dev >= NR_ST)
  285.       return (-ENODEV);
  286.     if (scsi_tapes[dev].in_use) {
  287.       printk("st%d: Device already in use.\n", dev);
  288.       return (-EBUSY);
  289.     }
  290.  
  291.     /* Allocate buffer for this user */
  292.     for (i=0; i < st_nbr_buffers; i++)
  293.       if (!st_buffers[i]->in_use)
  294.     break;
  295.     if (i >= st_nbr_buffers) {
  296.       printk("st%d: No free buffers.\n", dev);
  297.       return (-EBUSY);
  298.     }
  299.     st_buffers[i]->in_use = 1;
  300.     st_buffers[i]->writing = 0;
  301.     scsi_tapes[dev].buffer = st_buffers[i];
  302.     scsi_tapes[dev].in_use = 1;
  303.  
  304.     flags = filp->f_flags;
  305.     scsi_tapes[dev].write_prot = ((flags & O_ACCMODE) == O_RDONLY);
  306.  
  307.     scsi_tapes[dev].dirty = 0;
  308.     scsi_tapes[dev].rw = 0;
  309.     scsi_tapes[dev].eof = 0;
  310.     scsi_tapes[dev].eof_hit = 0;
  311.  
  312.     SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
  313.     if (!SCpnt) {
  314.       printk("st%d: Tape request not allocated", dev);
  315.       return (-EBUSY);
  316.     }
  317.  
  318.     SCpnt->sense_buffer[0]=0;
  319.     memset ((void *) &cmd[0], 0, 10);
  320.     cmd[0] = TEST_UNIT_READY;
  321.     SCpnt->request.dev = dev;
  322.     scsi_do_cmd(SCpnt,
  323.                 (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,
  324.                 ST_BLOCK_SIZE, st_sleep_done, ST_LONG_TIMEOUT,
  325.         MAX_READY_RETRIES);
  326.  
  327.     if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  328.  
  329.     if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
  330.     (SCpnt->sense_buffer[2] & 0x0f) == UNIT_ATTENTION) { /* New media? */
  331. #ifdef DEBUG
  332.       print_sense("st", SCpnt);
  333. #endif
  334.       SCpnt->sense_buffer[0]=0;
  335.       memset ((void *) &cmd[0], 0, 10);
  336.       cmd[0] = TEST_UNIT_READY;
  337.       SCpnt->request.dev = dev;
  338.       scsi_do_cmd(SCpnt,
  339.           (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,
  340.           ST_BLOCK_SIZE, st_sleep_done, ST_LONG_TIMEOUT,
  341.           MAX_READY_RETRIES);
  342.  
  343.       if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  344.     }
  345.  
  346.     if (SCpnt->result != 0) {
  347. #ifdef DEBUG
  348.       print_sense("st", SCpnt);
  349. #endif
  350.       if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
  351.       (SCpnt->sense_buffer[2] & 0x0f) == NO_TAPE)
  352.     printk("st%d: No tape.\n", dev);
  353.       else
  354.     printk("st%d: Error %x.\n", dev, SCpnt->result);
  355.       scsi_tapes[dev].buffer->in_use = 0;
  356.       scsi_tapes[dev].in_use = 0;
  357.       SCpnt->request.dev = -1;  /* Mark as not busy */
  358.       return (-EIO);
  359.     }
  360.  
  361.     SCpnt->sense_buffer[0]=0;
  362.     memset ((void *) &cmd[0], 0, 10);
  363.     cmd[0] = READ_BLOCK_LIMITS;
  364.     SCpnt->request.dev = dev;
  365.     scsi_do_cmd(SCpnt,
  366.                 (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,
  367.                 ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
  368.  
  369.     if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  370.  
  371.     if (!SCpnt->result && !SCpnt->sense_buffer[0]) {
  372.       scsi_tapes[dev].max_block = (scsi_tapes[dev].buffer->b_data[1] << 16) |
  373.     (scsi_tapes[dev].buffer->b_data[2] << 8) | scsi_tapes[dev].buffer->b_data[3];
  374.       scsi_tapes[dev].min_block = (scsi_tapes[dev].buffer->b_data[4] << 8) |
  375.     scsi_tapes[dev].buffer->b_data[5];
  376. #ifdef DEBUG
  377.       printk("st%d: Block limits %d - %d bytes.\n", dev, scsi_tapes[dev].min_block,
  378.          scsi_tapes[dev].max_block);
  379. #endif
  380.     }
  381.     else {
  382.       scsi_tapes[dev].min_block = scsi_tapes[dev].max_block = (-1);
  383. #ifdef DEBUG
  384.       printk("st%d: Can't read block limits.\n", dev);
  385. #endif
  386.     }
  387.  
  388.     SCpnt->sense_buffer[0]=0;
  389.     memset ((void *) &cmd[0], 0, 10);
  390.     cmd[0] = MODE_SENSE;
  391.     cmd[4] = 12;
  392.     SCpnt->request.dev = dev;
  393.     scsi_do_cmd(SCpnt,
  394.                 (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,
  395.                 ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
  396.  
  397.     if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  398.  
  399.     i = st_chk_result(SCpnt);
  400.     if (i) {
  401. #ifdef DEBUG
  402.       printk("st%d: No Mode Sense.\n", dev);
  403. #endif
  404.       scsi_tapes[dev].buffer->b_data[2] =
  405.       scsi_tapes[dev].buffer->b_data[3] = 0;
  406.     }
  407.     SCpnt->request.dev = -1;  /* Mark as not busy */
  408.  
  409. #ifdef DEBUG
  410.     printk("st%d: Mode sense. Length %d, medium %x, WBS %x, BLL %d\n", dev,
  411.        scsi_tapes[dev].buffer->b_data[0], scsi_tapes[dev].buffer->b_data[1],
  412.        scsi_tapes[dev].buffer->b_data[2], scsi_tapes[dev].buffer->b_data[3]);
  413. #endif
  414.  
  415.     if (scsi_tapes[dev].buffer->b_data[3] >= 8) {
  416.       scsi_tapes[dev].drv_buffer = (scsi_tapes[dev].buffer->b_data[2] >> 4) & 7;
  417.       scsi_tapes[dev].density = scsi_tapes[dev].buffer->b_data[4];
  418.       scsi_tapes[dev].block_size = scsi_tapes[dev].buffer->b_data[9] * 65536 +
  419.     scsi_tapes[dev].buffer->b_data[10] * 256 + scsi_tapes[dev].buffer->b_data[11];
  420. #ifdef DEBUG
  421.       printk("st%d: Density %x, tape length: %x, blocksize: %d, drv buffer: %d\n", dev,
  422.          scsi_tapes[dev].buffer->b_data[4], scsi_tapes[dev].buffer->b_data[5] *
  423.          65536 + scsi_tapes[dev].buffer->b_data[6] * 256 +
  424.          scsi_tapes[dev].buffer->b_data[7], scsi_tapes[dev].buffer->b_data[9] *
  425.          65536 + scsi_tapes[dev].buffer->b_data[10] * 256 +
  426.          scsi_tapes[dev].buffer->b_data[11],
  427.          scsi_tapes[dev].drv_buffer);
  428. #endif
  429.       if (scsi_tapes[dev].block_size > ST_BUFFER_SIZE) {
  430.     printk("st%d: Blocksize %d too large for buffer.\n", dev,
  431.            scsi_tapes[dev].block_size);
  432.     scsi_tapes[dev].buffer->in_use = 0;
  433.     scsi_tapes[dev].in_use = 0;
  434.     return (-EIO);
  435.       }
  436.  
  437.     }
  438.     else
  439.       scsi_tapes[dev].block_size = ST_BLOCK_SIZE;
  440.  
  441.     if (scsi_tapes[dev].block_size > 0) {
  442.       scsi_tapes[dev].buffer->buffer_blocks =
  443.     ST_BUFFER_SIZE / scsi_tapes[dev].block_size;
  444.       scsi_tapes[dev].buffer->buffer_size =
  445.     scsi_tapes[dev].buffer->buffer_blocks * scsi_tapes[dev].block_size;
  446.     }
  447.     else {
  448.       scsi_tapes[dev].buffer->buffer_blocks = 1;
  449.       scsi_tapes[dev].buffer->buffer_size = ST_BUFFER_SIZE;
  450.     }
  451.     scsi_tapes[dev].buffer->buffer_bytes = scsi_tapes[dev].buffer->read_pointer = 0;
  452.  
  453. #ifdef DEBUG
  454.     printk("st%d: Block size: %d, buffer size: %d (%d blocks).\n", dev,
  455.        scsi_tapes[dev].block_size, scsi_tapes[dev].buffer->buffer_size,
  456.        scsi_tapes[dev].buffer->buffer_blocks);
  457. #endif
  458.  
  459.     if (scsi_tapes[dev].buffer->b_data[2] & 0x80) {
  460.       scsi_tapes[dev].write_prot = 1;
  461. #ifdef DEBUG
  462.       printk( "st%d: Write protected\n", dev);
  463. #endif
  464.     }
  465.  
  466.     return 0;
  467. }
  468.  
  469.  
  470. /* Close the device*/
  471. static void scsi_tape_close(struct inode * inode, struct file * filp)
  472. {
  473.     int dev;
  474.     int result;
  475.     int rewind;
  476.     static unsigned char cmd[10];
  477.     Scsi_Cmnd * SCpnt;
  478.    
  479.     dev = MINOR(inode->i_rdev);
  480.     rewind = (dev & 0x80) == 0;
  481.     dev = dev & 127;
  482.  
  483.     if ( scsi_tapes[dev].rw == 2) {
  484.  
  485.       result = flush_write_buffer(dev);
  486.  
  487. #ifdef DEBUG
  488.       printk("st%d: File length %d bytes.\n", dev, filp->f_pos);
  489. #endif
  490.  
  491.       if (!result) {
  492.     SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
  493.  
  494.     SCpnt->sense_buffer[0] = 0;
  495.     memset(cmd, 0, 10);
  496.     cmd[0] = WRITE_FILEMARKS;
  497.     cmd[4] = 1;
  498.     SCpnt->request.dev = dev;
  499.     scsi_do_cmd( SCpnt,
  500.             (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,
  501.             ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
  502.  
  503.     if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  504.  
  505.     if (SCpnt->result) {
  506.       printk("st%d: Error on write filemark.\n", dev);
  507. #ifdef DEBUG
  508.       st_chk_result(SCpnt);
  509. #endif
  510.     }
  511.     SCpnt->request.dev = -1;  /* Mark as not busy */
  512.       }
  513.  
  514. #ifdef DEBUG
  515.       printk("st%d: Buffer flushed, EOF written\n", dev);
  516. #endif
  517.     }
  518.     else if (!rewind) {
  519.       if ((scsi_tapes[dev].eof == 1) && !scsi_tapes[dev].eof_hit)
  520.     st_int_ioctl(inode, filp, MTBSF, 1); /* Back over the EOF hit */
  521. #ifdef ST_IN_FILE_POS
  522.       flush_buffer(inode, filp, 0);
  523. #endif
  524.     }
  525.  
  526.     if (rewind)
  527.       st_int_ioctl(inode, filp, MTREW, 1);
  528.  
  529.     scsi_tapes[dev].buffer->in_use = 0;
  530.     scsi_tapes[dev].in_use = 0;
  531.  
  532.     return;
  533. }
  534.  
  535.  
  536. /* Write command */
  537. int st_write(struct inode * inode, struct file * filp, char * buf, int count)
  538. {
  539.     int dev;
  540.     int total, do_count, blks, retval;
  541.     static unsigned char cmd[10];
  542.     char *b_point;
  543.     Scsi_Cmnd * SCpnt;
  544.  
  545.     dev = MINOR(inode->i_rdev) & 127;
  546. #ifdef DEBUG
  547.     if (!scsi_tapes[dev].in_use) {
  548.       printk("st%d: Incorrect device.\n", dev);
  549.       return (-EIO);
  550.     }
  551. #endif
  552.  
  553.     if (scsi_tapes[dev].write_prot)
  554.       return (-EACCES);
  555.  
  556.     if (scsi_tapes[dev].block_size == 0 && count > ST_BUFFER_SIZE)
  557.       return (-EOVERFLOW);
  558.  
  559.     if (scsi_tapes[dev].rw == 1) {
  560.       retval = flush_buffer(inode, filp, 0);
  561.       if (retval)
  562.     return retval;
  563.       scsi_tapes[dev].rw = 2;
  564.     }
  565.  
  566. #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
  567.     if (scsi_tapes[dev].buffer->writing) {
  568.       write_behind_check(dev);
  569.       if (scsi_tapes[dev].buffer->last_result) {
  570. #ifdef DEBUG
  571.     printk("st%d: Async write error %x.\n", dev,
  572.            scsi_tapes[dev].buffer->last_result);
  573. #endif
  574.     /*if (scsi_tapes[dev].buffer->last_result = INT_MAX)
  575.       retval = (-ENOSPC);
  576.     else */
  577.       retval = (-EIO);
  578.     return retval;
  579.       }
  580.     }
  581. #endif
  582.  
  583.     SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
  584.  
  585.     total = count;
  586.  
  587.     memset(cmd, 0, 10);
  588.     cmd[0] = WRITE_6;
  589.     cmd[1] = (scsi_tapes[dev].block_size != 0);
  590.  
  591.     scsi_tapes[dev].rw = 2;
  592.  
  593.     b_point = buf;
  594.     while(
  595. #if ST_WRITE_THRESHOLD_BLOCKS  < ST_BUFFER_BLOCKS
  596.       scsi_tapes[dev].block_size != 0 &&
  597.       (scsi_tapes[dev].buffer->buffer_bytes + count) >
  598.       scsi_tapes[dev].buffer->buffer_size)
  599. #else
  600.       (scsi_tapes[dev].block_size == 0 && count > 0) ||
  601.       (scsi_tapes[dev].buffer->buffer_bytes + count) >=
  602.       scsi_tapes[dev].buffer->buffer_size)
  603. #endif
  604.     {
  605.       if (scsi_tapes[dev].block_size == 0)
  606.     do_count = count;
  607.       else
  608.     do_count = scsi_tapes[dev].buffer->buffer_size -
  609.       scsi_tapes[dev].buffer->buffer_bytes;
  610.       memcpy_fromfs(scsi_tapes[dev].buffer->b_data +
  611.             scsi_tapes[dev].buffer->buffer_bytes, b_point, do_count);
  612.  
  613.       if (scsi_tapes[dev].block_size == 0)
  614.         blks = do_count;
  615.       else
  616.     blks = scsi_tapes[dev].buffer->buffer_blocks;
  617.       cmd[2] = blks >> 16;
  618.       cmd[3] = blks >> 8;
  619.       cmd[4] = blks;
  620.       SCpnt->sense_buffer[0] = 0;
  621.       SCpnt->request.dev = dev;
  622.       scsi_do_cmd (SCpnt,
  623.            (void *) cmd, scsi_tapes[dev].buffer->b_data,
  624.            scsi_tapes[dev].buffer->buffer_size,
  625.            st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
  626.  
  627.       if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  628.  
  629.       if (SCpnt->result || SCpnt->sense_buffer[0] != 0) {
  630. #ifdef DEBUG
  631.     printk("st%d: Error on write:\n", dev);
  632.     st_chk_result(SCpnt);
  633. #endif
  634.     if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&
  635.         (SCpnt->sense_buffer[2] & 0x40))
  636.       retval = (-ENOSPC); /* EOM */
  637.     else
  638.       retval = (-EIO);
  639.     SCpnt->request.dev = -1;  /* Mark as not busy */
  640.     if (count < total)
  641.       return total - count;
  642.     else
  643.       return retval;
  644.       }
  645.       filp->f_pos += do_count;
  646.       b_point += do_count;
  647.       count -= do_count;
  648.       scsi_tapes[dev].buffer->buffer_bytes = 0;
  649.       scsi_tapes[dev].dirty = 0;
  650.     }
  651.     if (count != 0) {
  652.       scsi_tapes[dev].dirty = 1;
  653.       memcpy_fromfs(scsi_tapes[dev].buffer->b_data +
  654.             scsi_tapes[dev].buffer->buffer_bytes,b_point,count);
  655.       filp->f_pos += count;
  656.       scsi_tapes[dev].buffer->buffer_bytes += count;
  657.       count = 0;
  658.     }
  659.  
  660.     do_count = st_chk_result(SCpnt);
  661.     if (do_count) {
  662.       SCpnt->request.dev = -1;
  663.       return do_count;
  664.     }
  665.  
  666. #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
  667.     if (scsi_tapes[dev].buffer->buffer_bytes >= ST_WRITE_THRESHOLD ||
  668.     scsi_tapes[dev].block_size == 0) {
  669.       /* Schedule an asynchronous write */
  670.       if (scsi_tapes[dev].block_size == 0)
  671.     scsi_tapes[dev].buffer->writing = scsi_tapes[dev].buffer->buffer_bytes;
  672.       else
  673.     scsi_tapes[dev].buffer->writing = (scsi_tapes[dev].buffer->buffer_bytes /
  674.       scsi_tapes[dev].block_size) * scsi_tapes[dev].block_size;
  675.       scsi_tapes[dev].dirty = 0;
  676.  
  677.       if (scsi_tapes[dev].block_size == 0)
  678.     blks = scsi_tapes[dev].buffer->writing;
  679.       else
  680.     blks = scsi_tapes[dev].buffer->writing / scsi_tapes[dev].block_size;
  681.       cmd[2] = blks >> 16;
  682.       cmd[3] = blks >> 8;
  683.       cmd[4] = blks;
  684.       SCpnt->result = scsi_tapes[dev].buffer->last_result = -1;
  685.       SCpnt->sense_buffer[0] = 0;
  686.       SCpnt->request.dev = dev;
  687.       scsi_do_cmd (SCpnt,
  688.            (void *) cmd, scsi_tapes[dev].buffer->b_data,
  689.            scsi_tapes[dev].buffer->writing,
  690.            st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
  691.     }
  692.     else
  693. #endif
  694.       SCpnt->request.dev = -1;  /* Mark as not busy */
  695.  
  696.     return( total);
  697. }   
  698.  
  699.  
  700. /* Read command */
  701. int st_read(struct inode * inode, struct file * filp, char * buf, int count)
  702. {
  703.     int dev;
  704.     int total;
  705.     int transfer, blks, bytes;
  706.     static unsigned char cmd[10];
  707.     Scsi_Cmnd * SCpnt;
  708.  
  709.     dev = MINOR(inode->i_rdev) & 127;
  710. #ifdef DEBUG
  711.     if (!scsi_tapes[dev].in_use) {
  712.       printk("st%d: Incorrect device.\n", dev);
  713.       return (-EIO);
  714.     }
  715. #endif
  716.  
  717.     if (scsi_tapes[dev].block_size == 0 && count > ST_BUFFER_SIZE)
  718.       return (-EOVERFLOW);
  719.  
  720.     if (scsi_tapes[dev].rw == 2) {
  721.       transfer = flush_buffer(inode, filp, 0);
  722.       if (transfer)
  723.     return transfer;
  724.       scsi_tapes[dev].rw = 1;
  725.     }
  726.  
  727. #ifdef DEBUG
  728.     if (scsi_tapes[dev].eof)
  729.       printk("st%d: EOF flag up. Bytes %d\n", dev,
  730.          scsi_tapes[dev].buffer->buffer_bytes);
  731. #endif
  732.     if ((scsi_tapes[dev].buffer->buffer_bytes == 0) &&
  733.     scsi_tapes[dev].eof == 2)  /* EOM or Blank Check */
  734.       return (-EIO);
  735.  
  736.     scsi_tapes[dev].rw = 1;
  737.  
  738.     SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
  739.  
  740.     for (total = 0; total < count; ) {
  741.  
  742.       if (scsi_tapes[dev].buffer->buffer_bytes == 0 &&
  743.       scsi_tapes[dev].eof == 0) {
  744.  
  745.     memset(cmd, 0, 10);
  746.     cmd[0] = READ_6;
  747.     cmd[1] = (scsi_tapes[dev].block_size != 0);
  748.     if (scsi_tapes[dev].block_size == 0)
  749.       blks = bytes = count;
  750.     else {
  751.       blks = scsi_tapes[dev].buffer->buffer_blocks;
  752.       bytes = blks * scsi_tapes[dev].block_size;
  753.     }
  754.     cmd[2] = blks >> 16;
  755.     cmd[3] = blks >> 8;
  756.     cmd[4] = blks;
  757.  
  758.     SCpnt->sense_buffer[0] = 0;
  759.     SCpnt->request.dev = dev;
  760.     scsi_do_cmd (SCpnt,
  761.              (void *) cmd, scsi_tapes[dev].buffer->b_data,
  762.              scsi_tapes[dev].buffer->buffer_size,
  763.              st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
  764.  
  765.     if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  766.  
  767.     scsi_tapes[dev].buffer->read_pointer = 0;
  768.     scsi_tapes[dev].eof_hit = 0;
  769.  
  770.     if (SCpnt->result != 0 || SCpnt->sense_buffer[0] != 0) {
  771. #ifdef DEBUG
  772.       printk("st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev,
  773.          SCpnt->sense_buffer[0], SCpnt->sense_buffer[1],
  774.          SCpnt->sense_buffer[2], SCpnt->sense_buffer[3],
  775.          SCpnt->sense_buffer[4], SCpnt->sense_buffer[5],
  776.          SCpnt->sense_buffer[6], SCpnt->sense_buffer[7]);
  777. #endif
  778.       if ((SCpnt->sense_buffer[0] & 0x70) == 0x70) { /* extended sense */
  779.  
  780.         if ((SCpnt->sense_buffer[2] & 0xe0) != 0) { /* EOF, EOM, or ILI */
  781.           transfer = (SCpnt->sense_buffer[3] << 24) |
  782.         (SCpnt->sense_buffer[4] << 16) |
  783.           (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];
  784.  
  785.           if (SCpnt->sense_buffer[2] & 0x20) {
  786.         if (scsi_tapes[dev].block_size == 0) {
  787.           if (transfer <= 0)
  788.             transfer = 0;
  789.           scsi_tapes[dev].buffer->buffer_bytes = count - transfer;
  790.         }
  791.         else {
  792.           printk("st%d: Incorrect block size.\n", dev);
  793.           SCpnt->request.dev = -1;  /* Mark as not busy */
  794.           return (-EIO);
  795.         }
  796.           }
  797.           else if (SCpnt->sense_buffer[2] & 0x40) {
  798.         scsi_tapes[dev].eof = 2; /* What should be done at EOM ? */
  799.         scsi_tapes[dev].buffer->buffer_bytes =
  800.           (scsi_tapes[dev].buffer->buffer_blocks - transfer) *
  801.             scsi_tapes[dev].block_size;
  802. #ifdef DEBUG
  803.         printk("st%d: EOM detected (%d blocks read).\n", dev,
  804.                scsi_tapes[dev].buffer->buffer_blocks - transfer);
  805. #endif
  806.           }
  807.           else if (SCpnt->sense_buffer[2] & 0x80) {
  808.         scsi_tapes[dev].eof = 1;
  809.         if (scsi_tapes[dev].block_size == 0)
  810.           scsi_tapes[dev].buffer->buffer_bytes =
  811.             count - transfer;
  812.         else
  813.           scsi_tapes[dev].buffer->buffer_bytes =
  814.             (scsi_tapes[dev].buffer->buffer_blocks - transfer) *
  815.               scsi_tapes[dev].block_size;
  816. #ifdef DEBUG
  817.         printk("st%d: EOF detected (%d blocks read, transferred %d bytes).\n",
  818.                dev, scsi_tapes[dev].buffer->buffer_blocks - transfer, total);
  819. #endif
  820.           } /* end of EOF, EOM, ILI test */
  821.         }
  822.         else { /* nonzero sense key */
  823. #ifdef DEBUG
  824.           printk("st%d: Tape error. Sense key %x\n", dev,
  825.              SCpnt->sense_buffer[2] & 0x0f);
  826.           print_sense("st", SCpnt);
  827. #endif
  828.           SCpnt->request.dev = -1;
  829.           if (total)
  830.         return total;
  831.           else
  832.         return -EIO;
  833.         }
  834.       }
  835.       else {
  836.         transfer = st_chk_result(SCpnt);
  837.         SCpnt->request.dev = -1;  /* Mark as not busy */
  838.         return transfer;
  839.       }
  840.     }
  841.     else /* Read successfu| */
  842.       scsi_tapes[dev].buffer->buffer_bytes = bytes;
  843.  
  844.       } /* if (scsi_tapes[dev].buffer->buffer_bytes == 0 &&
  845.        scsi_tapes[dev].eof == 0) */
  846.  
  847.       if (scsi_tapes[dev].buffer->buffer_bytes > 0) {
  848. #ifdef DEBUG
  849.     if (scsi_tapes[dev].eof)
  850.       printk("st%d: EOF up. Left %d, needed %d.\n", dev,
  851.          scsi_tapes[dev].buffer->buffer_bytes, count - total);
  852. #endif
  853.     transfer = scsi_tapes[dev].buffer->buffer_bytes < count - total ?
  854.       scsi_tapes[dev].buffer->buffer_bytes : count - total;
  855.     memcpy_tofs(buf, scsi_tapes[dev].buffer->b_data +
  856.             scsi_tapes[dev].buffer->read_pointer,transfer);
  857.     filp->f_pos += transfer;
  858.     buf += transfer;
  859.     total += transfer;
  860.     scsi_tapes[dev].buffer->buffer_bytes -= transfer;
  861.     scsi_tapes[dev].buffer->read_pointer += transfer;
  862.       }
  863.       else if (scsi_tapes[dev].eof) {
  864.     scsi_tapes[dev].eof_hit = 1;
  865.     SCpnt->request.dev = -1;  /* Mark as not busy */
  866.     if (total == 0 && scsi_tapes[dev].eof == 1)
  867.       scsi_tapes[dev].eof = 0;
  868.     if (total == 0 && scsi_tapes[dev].eof == 2)
  869.       return (-EIO);
  870.     return total;
  871.       }
  872.  
  873.       if (scsi_tapes[dev].block_size == 0)
  874.     count = total;  /* Read only one variable length block */
  875.  
  876.     } /* for (total = 0; total < count; ) */
  877.  
  878.     SCpnt->request.dev = -1;  /* Mark as not busy */
  879.  
  880.     return total;
  881. }
  882.  
  883.  
  884. /* Internal ioctl function */
  885. static int st_int_ioctl(struct inode * inode,struct file * file,
  886.          unsigned int cmd_in, unsigned long arg)
  887. {
  888.    int dev = MINOR(inode->i_rdev);
  889.    int timeout = ST_LONG_TIMEOUT;
  890.    long ltmp;
  891.    int ioctl_result;
  892.    unsigned char cmd[10];
  893.    Scsi_Cmnd * SCpnt;
  894.  
  895.    dev = dev & 127;
  896.  
  897.    memset(cmd, 0, 10);
  898.    switch (cmd_in) {
  899.      case MTFSF:
  900.      case MTFSFM:
  901.        cmd[0] = SPACE;
  902.        cmd[1] = 0x01; /* Space FileMarks */
  903.        cmd[2] = (arg >> 16);
  904.        cmd[3] = (arg >> 8);
  905.        cmd[4] = arg;
  906. #ifdef DEBUG
  907.        printk("st%d: Spacing tape forward %d files.\n", dev,
  908.           cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
  909. #endif
  910.        break; 
  911.      case MTBSF:
  912.      case MTBSFM:
  913.        cmd[0] = SPACE;
  914.        cmd[1] = 0x01; /* Space FileMarks */
  915.        ltmp = (-arg);
  916.        cmd[2] = (ltmp >> 16);
  917.        cmd[3] = (ltmp >> 8);
  918.        cmd[4] = ltmp;
  919. #ifdef DEBUG
  920.        if (cmd[2] & 0x80)
  921.      ltmp = 0xff000000;
  922.        ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
  923.        printk("st%d: Spacing tape backward %d files.\n", dev, (-ltmp));
  924. #endif
  925.        break; 
  926.       case MTFSR:
  927.        cmd[0] = SPACE;
  928.        cmd[1] = 0x00; /* Space Blocks */
  929.        cmd[2] = (arg >> 16);
  930.        cmd[3] = (arg >> 8);
  931.        cmd[4] = arg;
  932. #ifdef DEBUG
  933.        printk("st%d: Spacing tape forward %d blocks.\n", dev,
  934.           cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
  935. #endif
  936.        break; 
  937.      case MTBSR:
  938.        cmd[0] = SPACE;
  939.        cmd[1] = 0x00; /* Space Blocks */
  940.        ltmp = (-arg);
  941.        cmd[2] = (ltmp >> 16);
  942.        cmd[3] = (ltmp >> 8);
  943.        cmd[4] = ltmp;
  944. #ifdef DEBUG
  945.        if (cmd[2] & 0x80)
  946.      ltmp = 0xff000000;
  947.        ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];
  948.        printk("st%d: Spacing tape backward %d blocks.\n", dev, (-ltmp));
  949. #endif
  950.        break; 
  951.      case MTWEOF:
  952.        if (scsi_tapes[dev].write_prot)
  953.      return (-EACCES);
  954.        cmd[0] = WRITE_FILEMARKS;
  955.        cmd[2] = (arg >> 16);
  956.        cmd[3] = (arg >> 8);
  957.        cmd[4] = arg;
  958.        timeout = ST_TIMEOUT;
  959. #ifdef DEBUG
  960.        printk("st%d: Writing %d filemarks.\n", dev,
  961.           cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);
  962. #endif
  963.        break; 
  964.      case MTREW:
  965.        cmd[0] = REZERO_UNIT;
  966. #ifdef ST_NOWAIT
  967.        cmd[1] = 1;  /* Don't wait for completion */
  968.        timeout = ST_TIMEOUT;
  969. #endif
  970. #ifdef DEBUG
  971.        printk("st%d: Rewinding tape.\n", dev);
  972. #endif
  973.        break; 
  974.      case MTOFFL:
  975.        cmd[0] = START_STOP;
  976. #ifdef ST_NOWAIT
  977.        cmd[1] = 1;  /* Don't wait for completion */
  978.        timeout = ST_TIMEOUT;
  979. #endif
  980. #ifdef DEBUG
  981.        printk("st%d: Unloading tape.\n", dev);
  982. #endif
  983.        break; 
  984.      case MTNOP:
  985. #ifdef DEBUG
  986.        printk("st%d: No op on tape.\n", dev);
  987. #endif
  988.        return 0;  /* Should do something ? */
  989.        break;
  990.      case MTRETEN:
  991.        cmd[0] = START_STOP;
  992. #ifdef ST_NOWAIT
  993.        cmd[1] = 1;  /* Don't wait for completion */
  994.        timeout = ST_TIMEOUT;
  995. #endif
  996.        cmd[4] = 3;
  997. #ifdef DEBUG
  998.        printk("st%d: Retensioning tape.\n", dev);
  999. #endif
  1000.        break; 
  1001.      case MTEOM:
  1002.        cmd[0] = SPACE;
  1003.        cmd[1] = 3;
  1004. #ifdef DEBUG
  1005.        printk("st%d: Spacing to end of recorded medium.\n", dev);
  1006. #endif
  1007.        break; 
  1008.      case MTERASE:
  1009.        if (scsi_tapes[dev].write_prot)
  1010.      return (-EACCES);
  1011.        cmd[0] = ERASE;
  1012.        cmd[1] = 1;  /* To the end of tape */
  1013. #ifdef DEBUG
  1014.        printk("st%d: Erasing tape.\n", dev);
  1015. #endif
  1016.        break;
  1017.      case MTSEEK:
  1018.        if (scsi_tapes[dev].device->scsi_level < SCSI_2) {
  1019.      cmd[0] = QFA_SEEK_BLOCK;
  1020.      cmd[2] = (arg >> 16);
  1021.      cmd[3] = (arg >> 8);
  1022.      cmd[4] = arg;
  1023.      cmd[5] = 0;
  1024.        }
  1025.        else {
  1026.      cmd[0] = SEEK_10;
  1027.      cmd[1] = 4;
  1028.      cmd[3] = (arg >> 24);
  1029.      cmd[4] = (arg >> 16);
  1030.      cmd[5] = (arg >> 8);
  1031.      cmd[6] = arg;
  1032.        }
  1033. #ifdef ST_NOWAIT
  1034.        cmd[1] |= 1;  /* Don't wait for completion */
  1035.        timeout = ST_TIMEOUT;
  1036. #endif
  1037. #ifdef DEBUG
  1038.        printk("st%d: Seeking tape to block %d.\n", dev, arg);
  1039. #endif
  1040.        break;
  1041.      case MTSETBLK:  /* Set block length */
  1042.      case MTSETDENSITY: /* Set tape density */
  1043.      case MTSETDRVBUFFER: /* Set drive buffering */
  1044.        if (scsi_tapes[dev].dirty || scsi_tapes[dev].buffer->buffer_bytes != 0)
  1045.      return (-EIO);   /* Not allowed if data in buffer */
  1046.        if (cmd_in == MTSETBLK &&
  1047.        arg != 0 &&
  1048.        (arg < scsi_tapes[dev].min_block || arg > scsi_tapes[dev].max_block ||
  1049.         arg > ST_BUFFER_SIZE)) {
  1050.      printk("st%d: Illegal block size.\n", dev);
  1051.      return (-EINVAL);
  1052.        }
  1053.        cmd[0] = MODE_SELECT;
  1054.        cmd[4] = 12;
  1055.  
  1056.        memset(scsi_tapes[dev].buffer->b_data, 0, 12);
  1057.        if (cmd_in == MTSETDRVBUFFER)
  1058.      scsi_tapes[dev].buffer->b_data[2] = (arg & 7) << 4;
  1059.        else
  1060.      scsi_tapes[dev].buffer->b_data[2] = 
  1061.        scsi_tapes[dev].drv_buffer << 4;
  1062.        scsi_tapes[dev].buffer->b_data[3] = 8;     /* block descriptor length */
  1063.        if (cmd_in == MTSETDENSITY)
  1064.      scsi_tapes[dev].buffer->b_data[4] = arg;
  1065.        else
  1066.      scsi_tapes[dev].buffer->b_data[4] = scsi_tapes[dev].density;
  1067.        if (cmd_in == MTSETBLK)
  1068.      ltmp = arg;
  1069.        else
  1070.      ltmp = scsi_tapes[dev].block_size;
  1071.        scsi_tapes[dev].buffer->b_data[9] = (ltmp >> 16);
  1072.        scsi_tapes[dev].buffer->b_data[10] = (ltmp >> 8);
  1073.        scsi_tapes[dev].buffer->b_data[11] = ltmp;
  1074.        timeout = ST_TIMEOUT;
  1075. #ifdef DEBUG
  1076.        if (cmd_in == MTSETBLK)
  1077.      printk("st%d: Setting block size to %d bytes.\n", dev,
  1078.         scsi_tapes[dev].buffer->b_data[9] * 65536 +
  1079.         scsi_tapes[dev].buffer->b_data[10] * 256 +
  1080.         scsi_tapes[dev].buffer->b_data[11]);
  1081.        else if (cmd_in == MTSETDENSITY)
  1082.      printk("st%d: Setting density code to %x.\n", dev,
  1083.         scsi_tapes[dev].buffer->b_data[4]);
  1084.        else
  1085.      printk("st%d: Setting drive buffer code to %d.\n",
  1086.         (scsi_tapes[dev].buffer->b_data[2] >> 4) & 7);
  1087. #endif
  1088.        break;
  1089.      default:
  1090.        printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);
  1091.        return (-ENOSYS);
  1092.      }
  1093.  
  1094.    SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
  1095.    SCpnt->sense_buffer[0] = 0;
  1096.    SCpnt->request.dev = dev;
  1097.    scsi_do_cmd(SCpnt,
  1098.            (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data, ST_BLOCK_SIZE,
  1099.            st_sleep_done, timeout, MAX_RETRIES);
  1100.  
  1101.    if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  1102.  
  1103.    ioctl_result = st_chk_result(SCpnt);
  1104.  
  1105.    SCpnt->request.dev = -1;  /* Mark as not busy */
  1106.  
  1107.    if (!ioctl_result) {
  1108.      if (cmd_in == MTBSFM)
  1109.        ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
  1110.      else if (cmd_in == MTFSFM)
  1111.        ioctl_result = st_int_ioctl(inode, file, MTBSF, 1);
  1112.      else if (cmd_in == MTSETBLK) {
  1113.        scsi_tapes[dev].block_size = arg;
  1114.        if (arg != 0) {
  1115.      scsi_tapes[dev].buffer->buffer_blocks =
  1116.        ST_BUFFER_SIZE / scsi_tapes[dev].block_size;
  1117.      scsi_tapes[dev].buffer->buffer_size =
  1118.        scsi_tapes[dev].buffer->buffer_blocks * scsi_tapes[dev].block_size;
  1119.        }
  1120.        else {
  1121.      scsi_tapes[dev].buffer->buffer_blocks = 1;
  1122.      scsi_tapes[dev].buffer->buffer_size = ST_BUFFER_SIZE;
  1123.        }
  1124.        scsi_tapes[dev].buffer->buffer_bytes =
  1125.      scsi_tapes[dev].buffer->read_pointer = 0;
  1126.      }
  1127.      else if (cmd_in == MTSETDRVBUFFER)
  1128.        scsi_tapes[dev].drv_buffer = arg;
  1129.      else if (cmd_in == MTSETDENSITY)
  1130.        scsi_tapes[dev].density = arg;
  1131.      if (cmd_in == MTEOM || cmd_in == MTWEOF) {
  1132.        scsi_tapes[dev].eof = 2;
  1133.        scsi_tapes[dev].eof_hit = 0;
  1134.      }
  1135.      else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {
  1136.        scsi_tapes[dev].eof = 0;
  1137.        scsi_tapes[dev].eof_hit = 0;
  1138.      }
  1139.    }
  1140.  
  1141.    return ioctl_result ;
  1142. }
  1143.  
  1144.  
  1145.  
  1146. /* The ioctl command */
  1147. static int st_ioctl(struct inode * inode,struct file * file,
  1148.          unsigned int cmd_in, unsigned long arg)
  1149. {
  1150.    int dev = MINOR(inode->i_rdev);
  1151.    int i, cmd, result;
  1152.    struct mtop mtc;
  1153.    struct mtpos mt_pos;
  1154.    unsigned char scmd[10];
  1155.    Scsi_Cmnd *SCpnt;
  1156.  
  1157.    dev = dev & 127;
  1158. #ifdef DEBUG
  1159.    if (!scsi_tapes[dev].in_use) {
  1160.      printk("st%d: Incorrect device.\n", dev);
  1161.      return (-EIO);
  1162.    }
  1163. #endif
  1164.  
  1165.    cmd = cmd_in & IOCCMD_MASK;
  1166.    if (cmd == (MTIOCTOP & IOCCMD_MASK)) {
  1167.  
  1168.      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(mtc))
  1169.        return (-EINVAL);
  1170.  
  1171.      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(mtc));
  1172.      if (i)
  1173.         return i;
  1174.  
  1175.      memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));
  1176.  
  1177.      i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
  1178.               mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
  1179.               mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM);
  1180.      if (i < 0)
  1181.        return i;
  1182.  
  1183.      return st_int_ioctl(inode, file, mtc.mt_op, mtc.mt_count);
  1184.    }
  1185.    else if (cmd == (MTIOCGET & IOCCMD_MASK)) {
  1186.  
  1187.      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtget))
  1188.        return (-EINVAL);
  1189.      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtget));
  1190.      if (i)
  1191.        return i;
  1192.  
  1193.      memcpy_tofs((char *)arg, (char *)scsi_tapes[dev].buffer->mt_status,
  1194.          sizeof(struct mtget));
  1195.      return 0;
  1196.    }
  1197.    else if (cmd == (MTIOCPOS & IOCCMD_MASK)) {
  1198. #ifdef DEBUG
  1199.      printk("st%d: get tape position.\n", dev);
  1200. #endif
  1201.      if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtpos))
  1202.        return (-EINVAL);
  1203.  
  1204.      i = flush_buffer(inode, file, 0);
  1205.      if (i < 0)
  1206.        return i;
  1207.  
  1208.      i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct mtpos));
  1209.      if (i)
  1210.        return i;
  1211.  
  1212.      SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
  1213.  
  1214.      SCpnt->sense_buffer[0]=0;
  1215.      memset (scmd, 0, 10);
  1216.      if (scsi_tapes[dev].device->scsi_level < SCSI_2) {
  1217.        scmd[0] = QFA_REQUEST_BLOCK;
  1218.        scmd[4] = 3;
  1219.      }
  1220.      else {
  1221.        scmd[0] = READ_POSITION;
  1222.        scmd[1] = 1;
  1223.      }
  1224.      SCpnt->request.dev = dev;
  1225.      SCpnt->sense_buffer[0] = 0;
  1226.      scsi_do_cmd(SCpnt,
  1227.          (void *) scmd, (void *) scsi_tapes[dev].buffer->b_data,
  1228.          ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
  1229.  
  1230.      if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
  1231.      
  1232.      if (SCpnt->result || SCpnt->sense_buffer[0]) {
  1233.        mt_pos.mt_blkno = (-1);
  1234. #ifdef DEBUG
  1235.        printk("st%d: Can't read tape position.\n", dev);
  1236. #endif
  1237.        result = (-EIO);
  1238.      }
  1239.      else {
  1240.        result = 0;
  1241.        if (scsi_tapes[dev].device->scsi_level < SCSI_2)
  1242.      mt_pos.mt_blkno = (scsi_tapes[dev].buffer->b_data[0] << 16) 
  1243.        + (scsi_tapes[dev].buffer->b_data[1] << 8) 
  1244.          + scsi_tapes[dev].buffer->b_data[2];
  1245.        else
  1246.      mt_pos.mt_blkno = (scsi_tapes[dev].buffer->b_data[4] << 24)
  1247.        + (scsi_tapes[dev].buffer->b_data[5] << 16) 
  1248.          + (scsi_tapes[dev].buffer->b_data[6] << 8) 
  1249.            + scsi_tapes[dev].buffer->b_data[7];
  1250.  
  1251.      }
  1252.  
  1253.      SCpnt->request.dev = -1;  /* Mark as not busy */
  1254.  
  1255.      memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));
  1256.      return result;
  1257.    }
  1258.    else
  1259.      return scsi_ioctl(scsi_tapes[dev].device, cmd_in, (void *) arg);
  1260. }
  1261.  
  1262.  
  1263.  
  1264. static struct file_operations st_fops = {
  1265.    NULL,            /* lseek - default */
  1266.    st_read,         /* read - general block-dev read */
  1267.    st_write,        /* write - general block-dev write */
  1268.    NULL,            /* readdir - bad */
  1269.    NULL,            /* select */
  1270.    st_ioctl,        /* ioctl */
  1271.    NULL,            /* mmap */
  1272.    scsi_tape_open,  /* open */
  1273.    scsi_tape_close, /* release */
  1274.    NULL            /* fsync */
  1275. };
  1276.  
  1277. void st_attach(Scsi_Device * SDp){
  1278.   scsi_tapes[NR_ST++].device = SDp;
  1279.   if(NR_ST > MAX_ST) panic ("scsi_devices corrupt (st)");
  1280. };
  1281.  
  1282. unsigned long st_init1(unsigned long mem_start, unsigned long mem_end){
  1283.   scsi_tapes = (Scsi_Tape *) mem_start;
  1284.   mem_start += MAX_ST * sizeof(Scsi_Tape);
  1285.   return mem_start;
  1286. };
  1287.  
  1288. /* Driver initialization */
  1289. unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
  1290. {
  1291.   int i;
  1292.  
  1293.   if (register_chrdev(MAJOR_NR,"st",&st_fops)) {
  1294.     printk("Unable to get major %d for SCSI tapes\n",MAJOR_NR);
  1295.     return mem_start;
  1296.   }
  1297.   if (NR_ST == 0) return mem_start;
  1298.  
  1299. #ifdef DEBUG
  1300.   printk("st: Init tape.\n");
  1301. #endif
  1302.  
  1303.   for (i=0; i < NR_ST; ++i) {
  1304.     scsi_tapes[i].capacity = 0xfffff;
  1305.     scsi_tapes[i].dirty = 0;
  1306.     scsi_tapes[i].rw = 0;
  1307.     scsi_tapes[i].eof = 0;
  1308.     scsi_tapes[i].waiting = NULL;
  1309.     scsi_tapes[i].in_use = 0;
  1310.     scsi_tapes[i].drv_buffer = 1;  /* Try buffering if no mode sense */
  1311.     scsi_tapes[i].density = 0;
  1312.   }
  1313.  
  1314.  
  1315.   /* Allocate the buffers */
  1316.   if (NR_ST == 1)
  1317.     st_nbr_buffers = 1;
  1318.   else
  1319.     st_nbr_buffers = 2;
  1320.   for (i=0; i < st_nbr_buffers; i++) {
  1321.     st_buffers[i] = (ST_buffer *) mem_start;
  1322. #ifdef DEBUG
  1323.     printk("st: Buffer address: %x\n", st_buffers[i]);
  1324. #endif
  1325.     mem_start += sizeof(ST_buffer) - 1 + ST_BUFFER_BLOCKS * ST_BLOCK_SIZE;
  1326.     st_buffers[i]->mt_status = (struct mtget *) mem_start;
  1327.     mem_start += sizeof(struct mtget);
  1328.     st_buffers[i]->in_use = 0;
  1329.     st_buffers[i]->writing = 0;
  1330.  
  1331.     /* "generic" status */
  1332.     memset((void *) st_buffers[i]->mt_status, 0, sizeof(struct mtget));
  1333.     st_buffers[i]->mt_status->mt_type = MT_ISSCSI1;
  1334.   }
  1335.  
  1336.   return mem_start;
  1337. }
  1338.